package custom.security.browser;

import custom.security.browser.authentication.CustomAuthticationSuccessHandler;
import custom.security.core.properties.SecurityProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.annotation.Resource;

/**
 * 基于浏览器的security配置
 * Created by wgt on 2017/10/12.
 */
@Configuration
public class BrowserSecurityConfigure extends WebSecurityConfigurerAdapter{

    @Resource(type = CustomUserDetailsService.class)
    private UserDetailsService userDetailsService;

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private AuthenticationSuccessHandler successHandler;

    @Autowired
    private AuthenticationFailureHandler failureHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //http.httpBasic();   //security 登陆框登陆

        http.formLogin()    //use form to login
                .loginPage("/authentication/require")    //指定用户登陆页面,用户需要进行验证登陆时跳转到该url
                .loginProcessingUrl("/authentication/form") //指定登陆请求url，UsernamePasswordAuthenticationFilter会拦截该路径
                .successHandler(successHandler)     //配置验证成功处理器
                .failureHandler(failureHandler)     //配置验证失败处理器
            .and()
                .authorizeRequests() //请求验证配置
                .antMatchers("/authentication/require",
                        "/image/code",
                        securityProperties.getBrowser().getLoginPage())    //过滤指定路径请求
                .permitAll()        //可以直接访问
                .anyRequest()       //以上请求外的任何请求
                .authenticated()    //都进行身份验证
            .and()
                .csrf()
                .disable()
        ;
    }



    /**
     * 使用自定义的用户详情和密码编码器
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        //return new Md5PasswordEncoder();
        return new BCryptPasswordEncoder();
    }
}
